home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / pcfilerd.arc / PCFILERD.C next >
Encoding:
C/C++ Source or Header  |  1988-09-20  |  4.1 KB  |  128 lines

  1. /*************************************************************
  2. *  PCFILERD.C - program from The C Gazette, Summer 88 issue, 
  3. *  Volume 2 No. 1. page 45.  The program demonstrates access
  4. *  to PC-FILE records by index and through the data records
  5. *  themselves. (c) 1988 Billy Rubin. Use freely but acknow-
  6. *  ledge author.
  7. *************************************************************/
  8.  
  9. /* The following two fields are dependent on the file layout. They
  10.    should ideally be set at compilation time as command line
  11.    switches so as to be tailored to specific layouts. They have
  12.    been commented out by typist as command line switches will
  13.    be used.
  14.       The typist used the Quick C Small memory model to compile
  15.    pcfilerd. My command line is:
  16.  
  17.    qcl /c /Zi /DRECLEN=75 /DFIELDS=4 pcfilerd.c
  18.  
  19.    The /c option is to create an object file.
  20.    The /Zi option is for compiling with Codeview information included.
  21.    The first /D option, /DRECLEN= 75, defines RECLEN from the comm-
  22.       and line. My records for this particular database are 75 columns,
  23.       not including spaces between fields or the carriage return.
  24.    The second /D option, /DFIELDS=4, defines FIELDS from the comm-
  25.       and line. In my database, there are 4 fields per record.
  26. */
  27.  
  28. /* #define RECLEN */    /* The length of the record as defined */
  29. /* #define FIELDS */    /* Number of fields in sample record */
  30.  
  31. #include <stdio.h>
  32. #include <string.h>
  33. #include <ctype.h>
  34.  
  35. #ifndef SEEK_SET
  36. #define SEEK_SET 0
  37. #endif
  38.  
  39. FILE *Idx_file;         /* The index file */
  40. FILE *Data_file;        /* The corresponding data file */
  41.  
  42. #define IDX_LEN   (FIELDS * 2 + 2)
  43. #define DATA_LEN  (RECLEN + 1)
  44.  
  45. char Idx_buffer [IDX_LEN];
  46. char Data_buffer [DATA_LEN];
  47.  
  48. void read_index()          /* Reads the next index record */
  49. {
  50.    fread (Idx_buffer, IDX_LEN, 1, Idx_file);
  51. }
  52.  
  53. unsigned int compute_offset()    /* Record offset is in last 2 bytes of Idx */
  54. {                                /* Since file begins at record 0, subtract */
  55.    unsigned int u;               /*    1 from record count.                 */
  56.    u = *( (unsigned int *) (Idx_buffer + IDX_LEN - 2));
  57.    return (u-1);
  58. }
  59.  
  60. void read_data()        /* Reads the next data record */
  61. {                       /* First gets record # from index file */
  62.                         /*  then goes to that location for data */
  63.    unsigned int offset;
  64.    long distance;
  65.    offset = compute_offset();    /* Get offset into data file */
  66.    distance = ( (long) offset * DATA_LEN);
  67.    fseek (Data_file, distance, SEEK_SET);
  68.    fread (Data_buffer, DATA_LEN, 1, Data_file);
  69. }
  70.  
  71. int get_record()
  72. {
  73.  
  74.    for( ;; ) {
  75.       read_index();
  76.       switch (Idx_buffer[0]) {   /* Test the first byte */
  77.          case '\\':              /* Backslash = EOF */
  78.             return (EOF);
  79.          case '/':               /* Forward slash = deleted record */
  80.             continue;
  81.          default:                /* Else it's a data record */
  82.             read_data();
  83.       }
  84.       break;
  85.    }
  86. }
  87.  
  88. void print_line()       /* Just a sample application: print the first */
  89. {                       /*     forty characters of the data record */
  90.  
  91.    char line [DATA_LEN];
  92.  
  93.    strncpy (line, Data_buffer, DATA_LEN);
  94.    if (strlen (line) > DATA_LEN - 1) /* Remember, strncpy() may not end */
  95.       line[DATA_LEN - 1] = '\0';     /*    the string with a null.      */
  96.    printf ("%s\n", line);
  97. }
  98.  
  99. main(argc, argv)
  100. int argc;
  101. char *argv [];
  102. {
  103.  
  104.    char idx_name [31], data_name [30];
  105.  
  106.    if (argc < 2) {
  107.       puts ("Usage: pcfilerd filename (no extension)");
  108.       exit (5);
  109.    }
  110.    else {   /* The file name is common to index and data files */
  111.       strcpy (idx_name, argv[1]);
  112.       strcat (idx_name,  ".inx");
  113.       strcpy (data_name, argv[1]);
  114.       strcat (data_name, ".dta");
  115.    }
  116.    if ( (Idx_file = (fopen (idx_name, "rb"))) == NULL) {
  117.       printf ("Error opening: %s\n", idx_name);
  118.       exit (5);
  119.    }
  120.    if ( (Data_file = (fopen (data_name, "rb"))) == NULL) {
  121.       printf ("Error opening: %s\n", data_name);
  122.       exit (6);
  123.    }
  124.    while (get_record() != EOF)
  125.       print_line();
  126. }
  127.  
  128.